package spark.network.protocol;

import spark.network.Util;
import spark.network.protocol.Base;

public class PreLogin extends Base {
	public static final short TYPE = 0x02;
	private static final byte[] TYPE_BYTES = Util.makeBytes(TYPE);

	/**
	 * Since no session has been established prior to prelogin the client sends a validation number in his pre login
	 * which the server has to put into the response
	 */
	private long validation;
	private static final int VALIDATION_OFFSET = Base.SIZE;
	private static final int VALIDATION_LENGTH = Long.SIZE / 8;

	/**
	 * Port on the machine performing the prelogin which should from here on receive responses. -1 if there is no
	 * explicit response port and the port which sent the message should be use for responses.
	 */
	private int responsePort = -1;
	private static final int RESPONSE_PORT_OFFSET = VALIDATION_OFFSET + VALIDATION_LENGTH;
	private static final int RESPONSE_PORT_LENGTH = Integer.SIZE / 8;

	private static final int SIZE =
			Base.SIZE +
			VALIDATION_LENGTH +
			RESPONSE_PORT_LENGTH;

	public PreLogin() {
		super(true, TYPE_BYTES);
	}

	public long getValidation() {
		return validation;
	}

	public void setValidation(long validation) {
		this.validation = validation;
	}

	public int getResponsePort() {
		return responsePort;
	}

	public void setResponsePort(int responsePort) {
		this.responsePort = responsePort;
	}

	@Override
	public void getBytes(byte[] buffer) {
		super.getBytes(buffer);
		Util.arraycopy(Util.makeBytes(validation), 0, buffer, VALIDATION_OFFSET);
		Util.arraycopy(Util.makeBytes(responsePort), 0, buffer, RESPONSE_PORT_OFFSET);
	}

	@Override
	public int getSize() {
		return SIZE;
	}

	@Override
	public void fill(byte[] buffer) {
		super.fill(buffer);
		validation = Util.makeLong(buffer, VALIDATION_OFFSET);
		responsePort = Util.makeInt(buffer, RESPONSE_PORT_OFFSET);
	}

	public static PreLogin create(byte[] buffer, long receiveTime) {
		PreLogin packet = new PreLogin();
		packet.fill(buffer);
		packet.setTimeStampReceive(receiveTime);
		return packet;
	}
}
